#ifndef MINIMAX_H
#define MINIMAX_H
#include <list>
#include <node.h>
#include <game_engine.h>


using namespace std;
class Utility;
//enum role { MAX_PLAYER, MIN_PLAYER };
class Minimax
{       
public: 
    explicit Minimax(GameEngine *);
    ~Minimax();

    int solver(Node* node, role r, int depth);
    int min_solver(Node *node, player p, int depth);
    int max_solver(Node *node, player p, int depth);


    Node* play(Node *node,  player p);
    int process_best_action(Node *node, player p, role r, int depth);
    void set_boards(Node *current);
    void backup_boards();
    void update_boards(Node *node, player p);
    player get_current_player();
    player get_opposite_player(player p);
    void restore_boards();
    void teste_play(Action *a);

    ReversiBoard save_black_board();
    ReversiBoard save_white_board();

    int call_alpha_beta(Node *node, role r, player p, int alpha, int beta, int depth);
    int alpha_beta(Node *node, role r, player p,  int alpha, int beta, int depth);

    void start();
    std::list<Action*> get_action_list(std::vector<int> &moves);
    Node* get_next_node(Node *node, Action *action);

    Action* get_next_action();
    void set_next_action(Action *action);
int white, black;
    int get_depth();
    void do_play(Action *a);

    Node* get_next_node(Node *node);
    Node *try_solve(Node *node, role player, int depth);

    Node *curr_black_node;
    Node *curr_white_node;

    void add_action(Action *action);
    Action* get_random_action();
    void erase_action_list();


    int r_count;
    void cpu_play();

    ReversiBoard backup_black_board;
    ReversiBoard backup_white_board;

    int backup_curr_col, backup_curr_row, backup_num_moves;
    bool backup_valid_move;

private:

    GameEngine *m_game_engine, copie_engine;
    int default_depth;
     std::vector<Action*> m_possible_actions;

    Node *m_white_node;
    Node *m_black_node;

    Node *backup_white_node;
    Node *backup_black_node;
    Action *m_next_action;
};

#endif // MINIMAX_H
